/**
 * 
 */
package org.oy.sealogger.logger;

import java.io.BufferedWriter;
import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Locale;
import java.util.Observable;
import java.util.Observer;
import java.util.Vector;

import org.oy.sealogger.common.Config;
import org.oy.sealogger.parser.CurrentState;
import org.oy.sealogger.parser.NMEA0183Sentence;
import org.oy.sealogger.parser.RMCSentence;
import org.oy.sealogger.route.WaypointData;

/**
 * @author juho
 *
 */
public class XMLLogger implements Observer {

	private NMEA0183Sentence sentence;
	private CurrentState state;
	private Vector<String> sentenceBuffer;
	private final int BUFFERSIZE = 8;
	private File filename = null;
	//private final static String NMEASTARTTAG = "<NMEASentences>";
	//public final static String NMEAENDTAG = "</NMEASentences>";
	public final static String LOGDIR = Config.getProperty("directory.logdir.name");
	
	private BufferedWriter out = null;
	
	public XMLLogger(CurrentState obs) {
		state = obs;
		sentenceBuffer = new Vector<String>();
	}

	public void update(Observable o, Object arg) {
		if (o == state && filename != null) {
			
			/* debug
			Random g = new Random();
			try {
				Thread.currentThread().sleep(g.nextInt(3)*1000);
			} catch (InterruptedException ioe) {
				
			}
			*/
			
			sentence = state.getGPSLocation();
			String GPSdata = null;
			if (sentence instanceof RMCSentence) {
				GPSdata = ((RMCSentence)sentence).getLocationXML();
			}
			if (GPSdata != null) {
				sentenceBuffer.add(GPSdata);
			}
		}
		
		// if buffer is full, we write it to the file
		if (sentenceBuffer.size() % BUFFERSIZE == 0) {
			writeToFile(sentenceBuffer);
			sentenceBuffer.clear();
		}
	}
	
	public void writeToFile(Vector<String> buffer) {
		for (String sentence : buffer) {
			writeToFile(sentence);
		}
	}

	public void writeToFile(String str) {
		try {
			out = new BufferedWriter(new FileWriter(filename, true));
			if (out != null) {
				saveStringToStream(out, str);
			}
		} catch (IOException ioe) {
			System.out.print(ioe);
		}
	}
	
	private void saveStringToStream(BufferedWriter out, String str) throws IOException {
		try {
			out.write(str);
			out.newLine();
		}
		finally {
			out.close();
		}
	}
	
	public void startLogging() {
		
		File currentDir = new File(System.getProperty("user.dir"));
		File logDir = new File(currentDir, LOGDIR);
		if (logDir.exists()) {
			System.out.println("Log directory found");
		} else {
			logDir.mkdir();
			System.out.println("Log directory created");
		}
		
		// generate filename
		SimpleDateFormat sdf = new SimpleDateFormat("EEE, d MMM yyyy HH.mm.ss ");
	
		String tmpfilename = sdf.format(new Date());
		tmpfilename += " log.xml";
		//String tmpfilename = DateFormat.getDateInstance().format(date) + " " + DateFormat.getTimeInstance(DateFormat.MEDIUM, Locale.GERMAN).format(date) + " log.xml";
		//tmpfilename = 
		filename = new File(logDir, tmpfilename);
		
		writeToFile(XMLTags.XMLDECLARATION);
		writeToFile("<"+XMLTags.DOCUMENT_TAG+">");
		
	}
	
	public void stopLogging() {
		// write the remaining sentences from the buffer 
		if (sentenceBuffer.size() > 0) {
			writeToFile(sentenceBuffer);
			sentenceBuffer.clear();
		}
		writeToFile("</"+XMLTags.DOCUMENT_TAG+">");
		filename = null;
	}
	
	public void logWaypoint(WaypointData waypoint) {
		sentenceBuffer.add(waypoint.toXMLString());
		
		// if buffer is full, we write it to the file
		if (sentenceBuffer.size() % BUFFERSIZE == 0) {
			writeToFile(sentenceBuffer);
			sentenceBuffer.clear();
		}
	}
}


